﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace VPN_Emulator
{
    //! Klasa reprezentująca drzewo MIB
    class MIBTree
    {
        //! główne okno programu 
         MainWindow parent;

        //! komponenty graficzne 
        private System.Windows.Forms.TreeView treeViewMIB;
        
        public System.Windows.Forms.TreeView TreeViewMIB
        {
            get { return treeViewMIB; }
            set { treeViewMIB = value; }
        }

        private FileStream file;
 
        //! przechowuje odwzorowanie miedzy OID i nazwą atrybutu
        private Dictionary<string, string> MIBDictionary;

        //! Konstruktor
        public MIBTree(MainWindow _parent,System.Windows.Forms.TreeView _mibTree):base()
        {
            parent = _parent;
            this.treeViewMIB = _mibTree;
            MIBDictionary = new Dictionary<string, string>();
            MyInit();
        }


        //! Inicjalizacja modułu
        public void MyInit()
        {

            System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("MIBTree");
            this.treeViewMIB.Location = new System.Drawing.Point(3, 2);
            this.treeViewMIB.Name = "treeViewMIB";
            treeNode1.Name = "MIB";
            treeNode1.Text = "MIBTree";
            this.treeViewMIB.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
            treeNode1});
            this.treeViewMIB.ShowNodeToolTips = true;
            this.treeViewMIB.TabIndex = 0;


        }


        //! Inicjalizacja drzewa MIB - wczytanie ikon dla drzewa MIB; wywołanie metod MIBTree służących wczytaniu poszczególnych modułów MIB na podstawie plików wejściowych .module
        public void MIBinitialization(ImageList il, String path)
        {
            //wczytanie ikon
            //to do: try/catch !!!!!
            il.Images.Add((System.Drawing.Image.FromFile(path + "\\Images\\" + "package_x_generic.png")));
            il.Images.Add((System.Drawing.Image.FromFile(path + "\\Images\\" + "text_x_generic.png")));
            il.Images.Add((System.Drawing.Image.FromFile(path + "\\Images\\" + "x_office_spreadsheet.png")));
            il.Images.Add((System.Drawing.Image.FromFile(path + "\\Images\\" + "application-x-executable.png")));
            il.Images.Add((System.Drawing.Image.FromFile(path + "\\Images\\" + "text-x-script.png")));
            il.Images.Add((System.Drawing.Image.FromFile(path + "\\Images\\" + "tree-icon.png")));
            TreeViewMIB.ImageList = il;
            TreeViewMIB.Nodes["MIB"].ImageIndex = 5;
            TreeViewMIB.Nodes["MIB"].SelectedImageIndex = 5;
            //wczytanie modułów
            MIBtree("BGP4-MIB.module", path);
            MIBtree("RFC1213-MIB.module", path);
            MIBtree("OSPF-MIB.module", path);
            MIBtree("MPLS-VPN-MIB.module", path);
        }

        //! Budowanie poddrzewa MIB w oparciu o plik wejściowy - otwiera plik wejściowy, tworzy węzły wraz z odpowiadającymi im ikonami, umiejscawia węzły w drzewie
        public void MIBtree(string modulename, string path)
        {
            string fileName = path + "\\Modules\\" + modulename;

            // Try to open the file
            try
            {
                file = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            }
            // If file doesnt exist, throw up an error message.
            catch (Exception)
            {
                System.Console.Out.WriteLine("Nie ma takiego pliku!");
                return;
            }

            string line = "";
            StreamReader stream = new StreamReader(file);

            //Zmienne ktore przetrzymuja stringi obecnie mielonej linijki
            string myOID, myType, myName, parentName;

            //Zmienne pomocnicza trzymajaca indexy ','
            int comaIndex1, comaIndex2, comaIndex3;

            while (!stream.EndOfStream)
            {
                line = stream.ReadLine();
                comaIndex1 = comaIndex2 = comaIndex3 = 0;
                myOID = myType = myName = parentName = "";

                if (!line.Contains('#') && !line.Equals("") && line.Contains(','))
                {
                    //System.Console.Out.WriteLine(line);
                    comaIndex1 = comaIndex2 = comaIndex3 = 0;

                    comaIndex1 = line.IndexOf(',');
                    comaIndex2 = line.IndexOf(',', comaIndex1 + 1);
                    comaIndex3 = line.IndexOf(',', comaIndex2 + 1);
                    //System.Console.Out.WriteLine("comaIndex1: " + comaIndex1);
                    //System.Console.Out.WriteLine("comaIndex2: " + comaIndex2);
                    //System.Console.Out.WriteLine("comaIndex2: " + comaIndex3);

                    myOID = line.Substring(line.IndexOf('.') + 1, comaIndex1 - 1);
                    myType = line.Substring(comaIndex1 + 1, comaIndex2 - comaIndex1 - 1);

                    //Skrocenie myType do samej nazwy?
                    myType = myType.Substring(23);

                    myName = line.Substring(comaIndex2 + 1, comaIndex3 - comaIndex2 - 1);
                    parentName = line.Substring(comaIndex3 + 1);

                    //System.Console.Out.WriteLine();
                    //System.Console.Out.WriteLine(myOID);
                    //System.Console.Out.WriteLine(myType);
                    //System.Console.Out.WriteLine(myName);
                    //System.Console.Out.WriteLine(parentName);

                    //stworzenie nowego wezła
                    TreeNode newNode = new System.Windows.Forms.TreeNode(myName);
                    myOID = "." + myOID;
                    newNode.Name = myOID;
                    newNode.ToolTipText = myOID;
                    //przypisanie obrazków
                    switch (myType)
                    {
                        case "ModuleIdentity":
                            newNode.ImageIndex = 0;
                            newNode.SelectedImageIndex = 0;
                            break;
                        case "OidValueAssignment":
                            newNode.ImageIndex = 0;
                            newNode.SelectedImageIndex = 0;
                            break;
                        case "ObjectType":
                            newNode.ImageIndex = 1;
                            newNode.SelectedImageIndex = 1;
                            break;

                        default:
                            newNode.ImageIndex = 1;
                            newNode.SelectedImageIndex = 1;
                            break;
                    }
                    if (myName.Contains("Table"))
                    {
                        newNode.ImageIndex = 2;
                        newNode.SelectedImageIndex = 2;
                    }
                    else if (myName.Contains("Entry"))
                    {
                        newNode.ImageIndex = 3;
                        newNode.SelectedImageIndex = 3;
                    }
                    else if (parentName.Contains("Entry"))
                    {
                        newNode.ImageIndex = 4;
                        newNode.SelectedImageIndex = 4;
                    }


                    //umiejscowienie wezła w drzewie
                    //nowa gałąź
                    if (treeViewMIB.Nodes.Find(newNode.Name, true).Length == 0 && !MIBDictionary.ContainsKey(parentName))
                    {
                        MIBDictionary.Add(myName, myOID);
                        treeViewMIB.Nodes["MIB"].Nodes.Add(newNode);
                    }
                    //doczepienie do istniejącej gałęzi
                    else if (treeViewMIB.Nodes.Find(newNode.Name, true).Length == 0 && MIBDictionary.ContainsKey(parentName))
                    {
                        MIBDictionary.Add(myName, myOID);
                        treeViewMIB.Nodes.Find(MIBDictionary[parentName], true)[0].Nodes.Add(newNode);
                    }
                }
            }
            stream.Close();
            return;
        }
   

        //! Funkcja translująca numeru OID na ciąg znakowy odpowiadający nazwie elementu drzewa MIB o tym OID
        public string translateIt(string getType, string oid, int index)
        {
            if (getType == "getTable")
            {
                //sprawdzenie czy dany obiekt jest w drzewie i czy jest tablicą
                TreeNode[] tab = treeViewMIB.Nodes.Find(oid, true);
                if (tab.Length == 1 && tab[0].ImageIndex == 2)
                {

                    //pętla po dzieciach Entry w tablicy
                    int licz = 0;
                    foreach (System.Windows.Forms.TreeNode i in tab[0].Nodes[0].Nodes)
                    {
                        if (licz == index)
                        {
                            return i.Text;
                        }
                        licz = licz + 1;
                    }
                }
            }

            else if (getType == "get")
            {
                TreeNode[] tab = null;

                if (oid.Substring(oid.Length - 2, 2) == ".0")
                {
                    tab = treeViewMIB.Nodes.Find(oid.Substring(0, oid.Length - 2), true);
                }
                else
                {
                    tab = treeViewMIB.Nodes.Find(oid, true);
                }
                if (tab != null && tab.Length == 1)
                {
                    return tab[0].Text;
                }
                //to moze byc obiekt tablicy (statyczny)
                else
                {
                    //pozycje  przedprzedostatniej kropki w oid'ie

                    int offset3 = 0;
                    int licznik = 0;

                    for (int i = oid.Length - 1; i > -1; i = i - 1)
                    {
                        if (oid[i] == '.')
                        {
                            licznik = licznik + 1;

                        }

                        if (licznik == 3)
                        {
                            offset3 = i;
                            break;
                        }


                    }


                    //sprawdzenie czy dany obiekt jest w drzewie i czy jest tablicą
                    TreeNode[] tab1 = treeViewMIB.Nodes.Find(oid.Substring(0, offset3), true);
                    if (tab1.Length == 1 && tab1[0].ImageIndex == 2)
                    {

                        //pętla po dzieciach Entry w tablicy
                        int licz = 0;
                        foreach (System.Windows.Forms.TreeNode i in tab1[0].Nodes[0].Nodes)
                        {
                            if (licz == index)
                            {
                                return i.Text;
                            }
                            licz = licz + 1;
                        }
                    }



                }

            }
            //jeśli nie znajdzie nazwy to zwraca null
            return null;

        }


    }
    }

